package main;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;

import javax.swing.border.EmptyBorder;
import javax.swing.text.DefaultEditorKit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.*;

import com.sun.awt.AWTUtilities;

import java.awt.Color;
import java.awt.Insets;
import java.text.DateFormat;
import java.util.Date;

public class Terminal extends JFrame {
	private static final long serialVersionUID = 1L;
	public String buffer; //the editable buffer
	public String other; //the uneditable main text field
	private JTextArea textArea;
	private JScrollPane scrollPane;
	private final char cursor = 171; // the '>>' symbol
	private JPanel contentPane;
	private InputHandler handler; //handler for the text
	private boolean cursorVisible = true;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					new Terminal();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame and initialize components
	 */
	public Terminal() {
		super("Command Prompt");
		setBackground(Color.DARK_GRAY);
		handler = new InputHandler(this);
		other = "";
		buffer = "";
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 500, 500);
		contentPane = new JPanel();
		contentPane.setBorder(null);
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		
		//set up the text area
		textArea = new JTextArea();
		textArea.setBorder(new EmptyBorder(10, 10, 10, 10));
		textArea.setForeground(Color.WHITE);
		textArea.setBackground(Color.BLACK);
		textArea.setLineWrap(true);
		textArea.setEditable(false);
		//add a key listener to write to the buffer
		textArea.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				if(e.getKeyCode() == KeyEvent.VK_ENTER){
					String temp = buffer;
					buffer += "\n";
					saveText();
					handler.processString(temp);
					addHeader();
				}else if(e.getKeyCode() == KeyEvent.VK_BACK_SPACE){
					if(buffer.length() > 0){
						buffer = buffer.substring(0, buffer.length()-1);
						setCursorVisible();
					}
				}else if(Character.isDefined(e.getKeyChar())){ //65-90 48-57
					buffer += e.getKeyChar();
					setCursorVisible();
				}
			}
		});
		
		//Get rid of the beep sound when backspace is pressed
		KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,0);
		InputMap inputMap = textArea.getInputMap();
		inputMap.put(key, DefaultEditorKit.defaultKeyTypedAction);
		
		//set up the scroll pane for the text area
		scrollPane = new JScrollPane();
		scrollPane.setBorder(null);
		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		scrollPane.setViewportView(textArea);
		contentPane.add(scrollPane, BorderLayout.CENTER);
		
		handleCursor();
		
		//initialize first line
		addHeader();
		
		//request focus
		setVisible(true);
		textArea.requestFocusInWindow();
	}
	
	//sets up the blinking cursor
	public void handleCursor(){
		Thread thread = new Thread(){
			public void run(){
				while(true){
					swapCursorState();
					try {
						Thread.sleep(800);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		thread.start();
	}
	
	public void swapCursorState(){
		cursorVisible = !cursorVisible;
		update();
	}
	
	public void setCursorVisible(){
		cursorVisible = true;
		update();
	}
	
	//writes and saves a string to a new line
	public void write(String s){
		saveText();
		other += ">"+s+"\n";
		update();
	}
	
	//Adds the default header to the start of the new line
	private void addHeader(){
		buffer = (char)171+DateFormat.getTimeInstance(DateFormat.SHORT).format(new Date())+(char)187+": ";
		saveText();
	}
	
	//updates the text in the text area
	public void update(){
		if(cursorVisible)
			textArea.setText(other+buffer+cursor);
		else
			textArea.setText(other+buffer);
	}
	
	//converts the text in the buffer into main text, and updates
	private void saveText(){
		other = other+buffer;
		buffer = "";
		update();
	}

}
